#include "AppService.h"
//正式采集连续帧图像cpp
AppService::AppService() : QObject(nullptr), m_config(Configuration::getInstance()) {
	// 设置线程池最大线程数
	m_threadPool.setMaxThreadCount(QThread::idealThreadCount());
}

AppService::~AppService() {
	qDebug() << "清空线程...";
	m_threadPool.clear();
	qDebug() << "清理串口资源...";
	m_485.close();
}

void AppService::connectCamera() {
	try {
		// 打开扫描相机
		m_camera.open();
		m_camera.setParams(m_config.camera);
		connect(&m_camera, &Camera::frameUpload, this, &AppService::onFrameReceive, Qt::QueuedConnection);
		connect(&m_camera, &Camera::frameReady, this, &AppService::frameReceive);
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::setCameraParams(const CameraConfig& config) {
	try {
		m_camera.stopLive();
		m_camera.setParams(config);
	} catch (const MyError& e) {
		throw e;
	}
}

void AppService::startCameraLive() {
	try {
		if (m_camera.isOpened()) {
			m_camera.startLive();
		}
		/*else
		{
			qDebug() << "!!!!!!!!!显示相机掉线，准备重新打开!!!!!!!!!!!!!";
			
			m_camera.open();
			if (m_camera.isOpened())
			{
				m_camera.startLive();
			}
		}*/
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::stopCameraLive() {
	try {
		if (m_camera.isOpened()) {
			m_camera.stopLive();
		}
	} catch (const MyError& e) {
		qCritical() <<"停止相机出现问题:"<< e.desc();
		throw e;
	}
}

void AppService::closeCamera() {
	try {
		stopCameraLive();
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::connectSerialPort() {
	try {
		QStringList portList;
		SerialPort::listPort(portList);
		qDebug() << "===============串口列表";
		qDebug() << "串口：" << portList;
		qDebug() << "               串口列表===================";

		if (portList.size() > 0) {
			m_485.openPort(m_config.serialPortConfig.serialNum);
			//设置电机运动模式
			m_485.initRunModel();
			//更新运动参数
			m_485.updateParams(m_config.serialPortConfig);
			//平台返回
			m_485.resetMoto();
		}
	}
	catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::connectServoPort()
{
	try {
		qDebug() << "串口：" << m_config.serialPortConfig.servoSerialNum;
		bool isOpen = m_serialPort.openServoPort(m_config.serialPortConfig.servoSerialNum);
		if (!isOpen) {
			std::cerr << "Servo serial port open failed!" << std::endl;
		}
	}
	catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::closeSerialPort() {}

void AppService::update485Params(const SerialPortConfig& config) { 
	try {
		m_485.updateParams(config);
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::movePlatformToTail() {
	//检测串口是否连?
	if (!m_485.isOpen()) {
		throw MyError(MyErrorType::SERIAL_OPEN_ERROR);
	}
	try {
		//开始扫描图
		m_485.moveMotoToTail([&]() {
			m_485.readData(8);
			qint64 beginTime = TimeUtils::getTimeGen();
			while (TimeUtils::getTimeGen() - beginTime < 6500) {
				QApplication::processEvents();
			}
		}, m_config.serialPortConfig.scannSpeed);
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::resetPlatform(bool waitReset) {
	if (!m_485.isOpen()) {
		throw MyError(MyErrorType::SERIAL_OPEN_ERROR);
	}
	try {
		//平台返回
		m_485.resetMoto(m_config.serialPortConfig.backSpeed, waitReset);
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::stopPlatformMove() {
	if (!m_485.isOpen()) {
		throw MyError(MyErrorType::SERIAL_OPEN_ERROR);
	}
	try {
		//平台返回
		m_485.stopMotor();
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::laserControl(QString enableLight)
{
	if (enableLight == QString("1")) {
		qInfo() << tr("下发打开激光器指令");
	}
	else {
		qInfo() << tr("下发关闭激光器指令");
	}
	QByteArray laserControlMark = enableLight.toUtf8();
	if (!m_serialPort.laserControl(laserControlMark))
	{
		qCritical() << "*******************laser control failed!!!";
	}
}

bool AppService::servoControl(QString controlData)
{
	QByteArray servoControlData = controlData.toUtf8();
	if (m_serialPort.servoControl(servoControlData)) {
		return true;
	}
	else
	{
		return false;
	}
}

bool AppService::activeWheelControl(QString controlData)
{
	QByteArray activeWheelControlData = controlData.toUtf8();
	if (m_serialPort.activeWheelControl(activeWheelControlData)) {
        return true;
	}
	return false;
}

bool AppService::passiveWheelControl(QString controlData)
{
    QByteArray passiveWheelControlData = controlData.toUtf8();
	if (m_serialPort.passiveWheelControl(passiveWheelControlData)) { return true; }
	return false;
}

void AppService::connectDatabase() {
	try {
		qInfo() << tr("开始初始化数据库...");
		if (Dao::initDatabase()) {
			if (m_dao.openDb()) {
				qInfo() << tr("数据库连接成功...");
			}
			else {
				qWarning() << tr("数据库连接失败...");
				throw MyError(MyErrorType::DATABASE_CONNECT_ERROR);
			}
		}
	}
	catch (const MyError& e) {
		qCritical() << e.what();
		throw e;
	}
}

void AppService::showTestData(QTableWidget* table, QList<DaoModel::TestData>& dataList, int minRows)
{
	//重置表格
	TableUtils::restTable(table, max(dataList.size(), minRows));
	for (int row = 0; row < dataList.size(); row++) {
		
		//获取数据
		DaoModel::TestData& data = dataList[row];
		//插入数据
		//牌号
		TableUtils::insertValue2Table(table, row, 0, data.brand());
		//编号
		TableUtils::insertValue2Table(table, row, 1, data.num());
		//最高点
		TableUtils::insertValue2Table(table, row, 2, data.maxHeight(), 2);
		//最低点
		TableUtils::insertValue2Table(table, row, 3, data.minHeight(),2);
		//平均值
		TableUtils::insertValue2Table(table, row, 4, data.meanHeight(),2);
		//标准方差
		TableUtils::insertValue2Table(table, row, 5, data.heightSD(),2);
		//异常区域
		TableUtils::insertValue2Table(table, row, 6, data.abnormalArea(),2);
	}
}

void AppService::clearDatabaseConnections() {}

QString AppService::getAppVersion() {
	return QString(PROJECT_VERSION.c_str());
}

QString AppService::getBuildType() {
	return QString(PROJECT_BUILD_TYPE.c_str());
}

Configuration& AppService::getConfig() {
	return m_config;
}

void AppService::saveConfig() { 
	try {
		m_config.saveConfig();
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::saveTestRecord(MyModel::TestRecord& record) { 

}

void AppService::saveTestData(MyModel::TestData& data) { 
}

void AppService::startTest() { 
	//检测串口是否连
	if (!m_485.isOpen()) {
		throw MyError(MyErrorType::SERIAL_OPEN_ERROR);
	}
	//检测相机是否连
	startCameraLive();
	if (!m_camera.isOpened()) {
		throw MyError(MyErrorType::CAMERA_NOT_CONNECT);
	}   
	try {
		// 创建单帧处理对象（行、列）
		m_imageProcessWorker = new ImageProcessWorker(500, m_config.camera.frameCount, m_config.imageProcessConfig,m_config.caliParas, this);
		connect(m_imageProcessWorker, &ImageProcessWorker::processFinished, this, &AppService::onScannerImageProcessFinished, Qt::QueuedConnection);

		//m_camera.startCollect(m_config.camera.frameCount);

		 //开始扫描图
		m_485.moveMotoToTail([&]() {
			m_485.readData(8);
			// 采集图像
			m_camera.startCollect(m_config.camera.frameCount);
			m_485.enablePrintLogger(false);
			while (m_485.getMotorPos() != RS485Port::POS_TAIL) {
				// 主线程处理界面刷
				QApplication::processEvents();
				qDebug() << "######################################################m_485.getMotorPos(): " << m_485.getMotorPos();
			}
			m_485.enablePrintLogger(true);
			}, m_config.serialPortConfig.scannSpeed);

		// 平台返回
		qDebug() << "########################### 平台位置返回 ###########################";
		m_485.resetMoto();
	} catch (const MyError& e) {
		qCritical() << e.desc();
		throw e;
	}
}

void AppService::stretchedFilm()
{
	this->servoControl(STRETCHED);//涨紧薄膜
}

void AppService::losseFilm()
{
	this->servoControl(LOOSE);//松紧薄膜
	delay(500, [=]() {
		this->servoControl(STOP);//打开夹具
	}, this);
}

void AppService::delay(int milliseconds, std::function<void()> callback, QObject* context)
{
	QTimer* timer = new QTimer;
	timer->setSingleShot(true); // 只触发一次

	// 自动清理内存（如果传了context，比如this，父对象销毁时会自动清理timer）
	if (context) {
		timer->setParent(context);
	}

	QObject::connect(timer, &QTimer::timeout, [=]() {
		callback();     // 时间到后执行你的代码
		timer->deleteLater(); // 清理计时器
		});

	timer->start(milliseconds); // 开始计时
}

void AppService::deleteRecords(qint64 m_id)
{
	m_dao.deleteRecord(m_id);
}

void AppService::saveData(DaoModel::TestData& data)
{
	m_dao.addTestData(data);
}

bool AppService::isDBOpen()
{
	return (m_dao.isOpened());
}

void AppService::querySqlTestRecords(QList<DaoModel::TestData>& records, QDate& beginDay, QDate& endDay, QString tester, QString schedule)
{
	m_dao.queryTestRecords(records, beginDay, endDay, tester, schedule);
}

void AppService::deleteSqlRecord(qint64 id)
{
	m_dao.deleteRecord(id);
}

void AppService::deleteSqlRecords(vector<qint64> ids)
{
	m_dao.deleteRecords(ids);
}

void AppService::querySqlTestData(QList<DaoModel::TestData>& dataList, QString createTime)
{
	m_dao.queryTestData(dataList, createTime);
}

void AppService::addSqlTestParam(const QString& tableName, const QString& name)
{
	m_dao.addTestParam(tableName, name);
}

void AppService::querySqlTestParam(const QString& tableName, QStringList& names)
{
	m_dao.queryTestParam(tableName, names);
}

void AppService::querySqlHistoryTestParams(QStringList& tester, QStringList& schedules)
{
	m_dao.queryHistoryTestParams(tester, schedules);
}

void AppService::onFrameReceive(int num, cv::Mat& frame) { 
	//qDebug() << "receive frame, num:" << num;
	// 上传给主窗口
	emit frameReceive(frame);
	
	QString saveImgName = QString("./data/%1.bmp").arg(QString::number(num));
    //QString saveImgName = QString("./data/%1.bmp").arg(QString::number(number1));
	imwrite(saveImgName.toStdString(), frame);
	/*m_camera.m_collectFlag = false;
	m_camera.m_frameNum = 0;
	number1++;*/
	/*if (m_camera.isCollectStart() && m_imageProcessWorker != nullptr) {
		m_imageProcessWorker->processFrameData(m_threadPool, num, frame);
	}*/
	if (num<m_config.camera.frameCount-1 && m_imageProcessWorker != nullptr) {
		m_imageProcessWorker->processFrameData(m_threadPool, num, frame);
	}
}

//void AppService::onScannerImageProcessFinished(cv::Mat& data) {
//	qDebug() << "扫描完成，创建数据分析任�?...";
//	const MyError& e = m_imageProcessWorker->getError();
//	if (e.code() != MyErrorType::NONE_ERROR.code) {
//		qWarning() << e.detail();
//	}
//	// 启动数据分析线程
//	DataAnalysisTask* dataAnalysisTask = new DataAnalysisTask(data);
//	connect(dataAnalysisTask, &DataAnalysisTask::finished, this, &AppService::onDataAnalysisTaskFinished);
//	//释放ScannerImageProcessWorker
//	qDebug() << "释放ScannerImageProcessWorker...";
//	m_imageProcessWorker->deleteLater();
//}


void AppService::onScannerImageProcessFinished(pcl::PointCloud<pcl::PointXYZ>::Ptr& data,staticalParameters cloudStaticData) {
	// 将点云数据传到界�?
	emit sendCloud2mainwindow(data, cloudStaticData);
	m_imageProcessWorker->deleteLater();
}



//void AppService::onScannerImageProcessFinished(vector<cv::Vec3f>& data) {
//	qDebug() << "扫描完成，创建数据分析任�?...";
//	const MyError& e = m_imageProcessWorker->getError();
//	if (e.code() != MyErrorType::NONE_ERROR.code) {
//		qWarning() << e.detail();
//	}
//	// 启动数据分析线程
//	/*DataAnalysisTask* dataAnalysisTask = new DataAnalysisTask(data);
//	connect(dataAnalysisTask, &DataAnalysisTask::finished, this, &AppService::onDataAnalysisTaskFinished);*/
//	//释放ScannerImageProcessWorker
//	qDebug() << "释放ScannerImageProcessWorker...";
//	m_imageProcessWorker->deleteLater();
//}



void AppService::onDataAnalysisTaskFinished() {
	qDebug() << "数据分析完成...";
	//上传处理结果
	/*emit testFinished();*/
	DataAnalysisTask* task = (DataAnalysisTask*)sender();
	MyError e = task->getError();
	if (e.code() == MyErrorType::NONE_ERROR.code) {
		
	} else {
		qWarning() << e.detail();
	}

	qDebug() << "销毁数据分析线�?...";
	task->deleteLater();
}

